package com.baizhi.security;

import com.baizhi.service.IBzAdminService;
import com.baizhi.service.impl.BzAdminServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


/**
 * @EnableWebSecurity 开启SpringSecurity
 *
 * WebSecurityConfigurerAdapter 该类是SpringSecurity的默认配置
 * 例如：默认的登录页面 默认的账号密码
 *
 */
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private BzAdminServiceImpl bzAdminService;
    /**
     * Authentication 认证的意思
     * 在shiro和SpringSecurity中 所有以Authen开头的单词都和认证业务有关系
     *
     * 定义数据源 定义要不要使用数据库的数据 或者使用假数据
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /**
         * 制造假的认证用户数据
         *
         * inMemoryAuthentication 在内存中制造假数据
         * withUser 定义账号
         * password 定义密码 但是SpringSecurity默认加密 如果不想使用加密 需要给密码
         * 添加前缀 {noop} 该前缀是一种声明用于让SpringSEcurity知道密码的加密方式 前缀
         * 不参与密码校验
         * roles 是角色 和授权有关系
         */
/*
        auth.inMemoryAuthentication()
                .withUser("zhangsan")
                .password("{noop}123456")
                .roles("ADMIN")
                .and()
                .withUser("lisi")
                .password("{noop}123456")
                .roles("ADMIN");
*/


        //        声明使用UserDetailService
        auth.userDetailsService(bzAdminService)
//                passwordEncoder 执行加密规则
              .passwordEncoder(bCryptPasswordEncoder());
}

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
    /**
     * HttpSecurity 配置拦截规则 跳转 和 自定义登录页面
     *
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**
         * authorizition 授权
         * 在shiro和SpringSecurity中 所有以Author开头的单词都和授权业务有关系
         *
         * authorizeRequests 配置拦截规则
         * antMatchers 配置路径
         * permitAll 不拦截
         */
        http.authorizeRequests()
//                配置不拦截
                .antMatchers("/admin/**","/img/**","/css/**","/js/**","/ztree/**","/login.jsp","/login","/layui/**")
                .permitAll()
//                拦截所有 配置一般不会使用/** 而是独立配置
//                anyRequest 代表所有路径
                .anyRequest()
                .authenticated();
        /**
         * 自定义登录页面
         *
         * formLogin() 代表表单登录
         * loginPage 自定义登录页面
         * loginProcessingUrl 定义登录方法的地址 /login就是SpringSecurity中的认证方法
         * successForwardUrl 登录成功后的地址
         * failureForwardUrl 登录失败后的地址
         */
        http.formLogin()
                .loginPage("/login.jsp")
                .successForwardUrl("/main.jsp")
                .failureForwardUrl("/login.jsp")
                .loginProcessingUrl("/login")
                .and()
                .csrf()
                .disable()
        ;

//       html iframe标签引用二级页面 会被默认拦截
//        可以配置不拦截
        http.headers().frameOptions().disable();
    }
}
